home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
pcr
/
pcr4_4.lha
/
DIST
/
threads
/
ThreadsUIOShMem.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-08
|
7KB
|
352 lines
/* begincopyright
Copyright (c) 1988 Xerox Corporation. All rights reserved.
Use and copying of this software and preparation of derivative works based
upon this software are permitted. Any distribution of this software or
derivative works must comply with all applicable United States export
control laws. This software is made available AS IS, and Xerox Corporation
makes no warranty about the software, its performance or its conformity to
any specification. Any person obtaining a copy of this software is requested
to send their name and post office or electronic mail address to:
PCR Coordinator
Fuji Xerox IWA
endcopyright */
/*
* ThreadsUIOShMem.c
*
* Yasuhiko Aizawa December 12, 1989 3:03:15 pm PST
* Demers, February 12, 1990 3:15:26 pm PST
* Boehm, June 7, 1990 11:21:23 am PDT
*
* Unix SharedMem simulation (for IPC MMap_loader etc),
* for Xerox Runtime threads package.
*/
#include "xr/Threads.h"
#include "xr/ThreadsBackdoor.h"
#include "xr/ThreadsSharedMem.h"
#include "xr/ThreadsMsgPrivate.h"
#include "xr/UIO.h"
#include "xr/UIOPrivate.h"
#include "xr/Errno.h"
/*
* UNIX (SunOS 4.0) dependent memory management ...
*/
#include <sys/types.h>
#include <sys/file.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define DEBUG_SHM 0
/*
* ShmAt / ShmDt / ShmGet /ShmCtl
*/
typedef struct XR_ShmArgsRep {
int shm_id;
XR_Pointer shm_addr;
int shm_flags;
int shm_results[XR_MAX_VPS+XR_MAX_IOPS];
} * XR_ShmArgs;
/* where to put a result ... */
#define ResultIndex() ((XR_vpe != NIL) \
? XR_vpe->vpe_index \
: XR_MAX_VPS + XR_iope->iope_index )
/* VP order issuer (runs in IOP) */
static int /* -errno */
XR_ShmIOPIssueVPOrder (sha, proc)
XR_ShmArgs sha;
void (*proc)(/* XR_VPOrder vpo */);
{
int i, ans;
XR_iope->iope_vpOrderBuf.vpo_sha = ((unsigned)(sha));
XR_IssueVPOrder(
/*order*/ &(XR_iope->iope_vpOrderBuf),
/*proc*/ proc,
/*stop*/ FALSE
);
for( i = 0; i < XR_maxVPs; i++ ) {
if( (ans = sha->shm_results[i]) != 0 ) return ans;
}
return 0;
}
/* shmat primitives */
static bool
XR_ValidAddressRangeForShm(addr)
XR_Pointer addr;
{
if( addr != XR_ComputeAddress(addr, 0, XR_ROUND_DOWN) ) {
/* not page-aligned */
return FALSE;
}
return TRUE;
}
static int /* -errno */
XR_DoShmAtProc (sha)
XR_ShmArgs sha;
{
XR_Pointer shmatAns;
int theResult = 0;
#if DEBUG_SHM
XR_ConsoleMsg("%? DoShmAtProc id %d addr 0x%x flags 0x%x\n",
sha->shm_id, sha->shm_addr, sha->shm_flags);
#endif
shmatAns = (XR_Pointer) shmat(
sha->shm_id,
sha->shm_addr,
sha->shm_flags);
if( shmatAns != sha->shm_addr) {
theResult = -errno;
XR_ConsoleMsg("%? DoShmAtProc shmat ans 0x%x errno %d\n",
shmatAns, -theResult);
XR_ConsoleMsg("DoShmAtProc id %d addr 0x%x flags 0x%x\n",
sha->shm_id, sha->shm_addr, sha->shm_flags);
}
sha->shm_results[ResultIndex()] = theResult;
return theResult;
}
/* ShmAt VP Procs */
void
XR_ShmAtVPOrderProc (vpo)
XR_VPOrder vpo;
{
XR_ShmArgs sha = (XR_ShmArgs)(vpo->vpo_sha);
if( XR_vpe == NIL )
XR_Panic("ShmAtVPOrderProc 0");
(void) XR_DoShmAtProc(sha);
}
/* ShmAt IOP Procs */
void
XR_ShmAtIOPOrderProc (iopo)
XR_IOPOrder iopo;
{
int ans;
XR_ShmArgs sha = ((XR_ShmArgs)(iopo->iopo_sha));
ans = XR_DoShmAtProc(sha);
if( (ans == 0) && (XR_iope->iope_index == 0) ) {
ans = XR_ShmIOPIssueVPOrder(sha, XR_ShmAtVPOrderProc);
}
iopo->iopo_results[0] = ((unsigned)(ans));
# if DEBUG_SHM
XR_ConsoleMsg("%? ShmAtIOPOrderProc done\n");
# endif
XR_UIONotifyIOPODone(iopo);
}
/* ShmAt Exported to UIO.h */
int
XR_ShmAt(id, addr, flags)
int id;
XR_Pointer addr;
int flags;
{
struct XR_ShmArgsRep sha;
struct XR_IOPOrderRep iopo;
XR_IOPOResult iopoResult;
int ans, savedErrno;
if( !XR_ValidAddressRangeForShm(addr) ) {
XR_SetErrno(EINVAL);
return(-1);
}
(void) bzero( &sha, (sizeof sha) );
sha.shm_id = id;
sha.shm_addr = addr;
sha.shm_flags = flags;
iopo.iopo_sha = ((unsigned)(&sha));
iopoResult = XR_IssueIOPOrders(
/*order*/ &iopo,
/*remoteProc*/ XR_ShmAtIOPOrderProc,
/*localProc*/ NIL
);
if( iopoResult != XR_IOPO_RESULT_OK ) {
XR_Panic("ShmAt 0");
}
ans = ((int)(iopo.iopo_results[0]));
if( ans != 0 ) {
(void) XR_ShmDt(addr);
XR_SetErrno(-ans);
return (-1);
}
return addr;
}
/* ShmDt primitives */
static int /* -errno */
XR_DoShmDtProc(sha)
XR_ShmArgs sha;
{
int shmdtAns;
int theResult = 0;
#if DEBUG_SHM
XR_ConsoleMsg("DoShmDtProc addr %d \n", sha->shm_addr);
#endif
shmdtAns = shmdt( sha->shm_addr );
if( shmdtAns != 0) {
theResult = -errno;
XR_ConsoleMsg("%? DoShmDtProc shmdt errno addr %d\n",
-theResult, sha->shm_addr);
}
sha->shm_results[ResultIndex()] = theResult;
return theResult;
}
/* ShmDt VP Procs */
void
XR_ShmDtVPOrderProc(vpo)
XR_VPOrder vpo;
{
XR_ShmArgs sha = (XR_ShmArgs)(vpo->vpo_sha);
if( XR_vpe == NIL )
XR_Panic("MUnmapVPOrderProc 0");
(void) XR_DoShmDtProc(sha);
}
/* ShmDt IOP Procs */
void
XR_ShmDtIOPOrderProc (iopo)
XR_IOPOrder iopo;
{
int ans, vpAns;
XR_ShmArgs sha = ((XR_ShmArgs)(iopo->iopo_sha));
ans = XR_DoShmDtProc(sha);
vpAns = ( (XR_iope->iope_index == 0)
? XR_ShmIOPIssueVPOrder(sha, XR_ShmDtVPOrderProc)
: 0 );
iopo->iopo_results[0] = ( (unsigned)((ans < 0) ? ans : vpAns) );
XR_UIONotifyIOPODone(iopo);
}
/* ShmDt Exported to UIO.h */
int
XR_ShmDt(addr)
XR_Pointer addr;
{
struct XR_ShmArgsRep sha;
struct XR_IOPOrderRep iopo;
XR_IOPOResult iopoResult;
int ans;
if( !XR_ValidAddressRangeForShm(addr) ) {
XR_SetErrno(EINVAL);
return(-1);
}
(void)bzero( &sha, (sizeof sha) );
sha.shm_addr = addr;
iopo.iopo_sha = ((unsigned)(&sha));
iopoResult = XR_IssueIOPOrders(
/*order*/ &iopo,
/*proc*/ XR_ShmDtIOPOrderProc,
/*localProc*/ NIL
);
if( iopoResult != XR_IOPO_RESULT_OK ) {
XR_Panic("XR_ShMdt 0");
}
ans = ((int)(iopo.iopo_results[0]));
if( ans < 0 ) {
XR_SetErrno(-ans);
return (-1);
}
return 0;
}
/* ShmGet exported to UIO.h */
int
XR_ShmGet(key, size, shmflg)
int key;
int size;
int shmflg;
{
return(shmget(key,size,shmflg));
}
/* ShmCtl exported to UIO.h */
int
XR_ShmCtl(shmid, cmd, buf)
int shmid;
int cmd;
struct shmid_ds *buf;
{
switch(cmd) {
case IPC_SET:
case IPC_RMID:
return(shmctl(shmid,cmd,buf));
case IPC_STAT:
{
struct shmid_ds myBuf;
int ans;
ans = shmctl(shmid, IPC_STAT, &myBuf);
*buf = myBuf;
return(ans);
}
default:
XR_SetErrno(EINVAL);
return(-1);
}
}